home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / WINPROGS / UPC12BS1.ZIP / LIB / WINUTIL.C < prev    next >
C/C++ Source or Header  |  1993-10-02  |  12KB  |  331 lines

  1. /*--------------------------------------------------------------------*/
  2. /*       w i n u t i l . h                                            */
  3. /*                                                                    */
  4. /*       Windows 3.1 utility functions for UUPC/extended              */
  5. /*--------------------------------------------------------------------*/
  6.  
  7. /*--------------------------------------------------------------------*/
  8. /*       Copyright (c) Robert Denny, 1993                             */
  9. /*--------------------------------------------------------------------*/
  10.  
  11. /*--------------------------------------------------------------------*/
  12. /*       Changes Copyright (c) 1989-1993 by Kendra Electronic         */
  13. /*       Wonderworks.                                                 */
  14. /*                                                                    */
  15. /*       All rights reserved except those explicitly granted by       */
  16. /*       the UUPC/extended license agreement.                         */
  17. /*--------------------------------------------------------------------*/
  18.  
  19. /*--------------------------------------------------------------------*/
  20. /*                          RCS Information                           */
  21. /*--------------------------------------------------------------------*/
  22.  
  23. /*
  24.  *    $Id: winutil.c 1.5 1993/10/02 19:07:49 ahd Exp $
  25.  *
  26.  *    Revision history:
  27.  *    $Log: winutil.c $
  28.  * Revision 1.5  1993/10/02  19:07:49  ahd
  29.  * Print module name when winexec() fails
  30.  *
  31.  * Revision 1.4  1993/08/03  03:11:49  ahd
  32.  * Further Windows 3.x fixes
  33.  *
  34.  * Revision 1.3  1993/08/02  03:24:59  ahd
  35.  * Further changes in support of Robert Denny's Windows 3.x support
  36.  *
  37.  * Revision 1.2  1993/07/31  16:22:16  ahd
  38.  * Changes in support of Robert Denny's Windows 3.x support
  39.  *
  40.  * Revision 1.1  1993/07/22  23:19:50  ahd
  41.  * Initial revision
  42.  *
  43.  */
  44.  
  45. /*--------------------------------------------------------------------*/
  46. /*                        System include files                        */
  47. /*--------------------------------------------------------------------*/
  48.  
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #include <string.h>
  52. #include <windows.h>
  53. #include <toolhelp.h>
  54.  
  55. /*--------------------------------------------------------------------*/
  56. /*                    UUPC/extended include files                     */
  57. /*--------------------------------------------------------------------*/
  58.  
  59. #include "lib.h"
  60. #include "winutil.h"
  61.  
  62. /*--------------------------------------------------------------------*/
  63. /*                           Local defines                            */
  64. /*--------------------------------------------------------------------*/
  65.  
  66. /*--------------------------------------------------------------------*/
  67. /*                          Private messages                          */
  68. /*--------------------------------------------------------------------*/
  69.  
  70. #define PM_TASKEND WM_USER
  71.  
  72. /*--------------------------------------------------------------------*/
  73. /*      Globals needed by callback functions & useful elsewhere       */
  74. /*--------------------------------------------------------------------*/
  75.  
  76. HTASK hOurTask;               // Our task handle
  77. HWND hOurWindow;              // Our EasyWin main window handle
  78.  
  79. /*--------------------------------------------------------------------*/
  80. /*                         Used only locally                          */
  81. /*--------------------------------------------------------------------*/
  82.  
  83. static HINSTANCE hChildInst;            // Instance of child proc
  84. static HWND hTheWindow;                 // Used by WindCatcher() during enumeration
  85.  
  86.  
  87. BOOL CALLBACK WindCatcher(HWND hWnd, LPARAM lparam);
  88. BOOL CALLBACK NotifyCatcher(WORD wID, DWORD dwData);
  89.  
  90. static LPFNNOTIFYCALLBACK lpfnNotifyCB;
  91. static FARPROC lpfnEnumWinCB;
  92.  
  93. void _DoneEasyWin(void);      // In TCWIN library
  94.  
  95. //------------------------------------------------------------------------
  96. //
  97. // CloseEasyWin() - Force EasyWin window to close on termination
  98. //
  99. // This function should be registered with a call to atexit() if
  100. // you want to force the EasyWin window to close, permitting the
  101. // application to exit, automatically. Normally, an EasyWin app
  102. // hangs out in the "inactive" state until the user manually closes
  103. // the window. Using an atexit() function assures that the app will
  104. // exit automatically, regardless of the means of generating the
  105. // exit action (such as Ctrl-SysReq signal handlers, etc.).
  106. //
  107. //------------------------------------------------------------------------
  108. void CloseEasyWin(void)
  109. {
  110.    MSG msg;
  111.  
  112.    //
  113.    // This will assure that the EasyWin task yields to the system
  114.    // at least once before exiting. See the comments next to the
  115.    // call to WinExec() below.
  116.    //
  117.    PeekMessage(&msg, hOurWindow, NULL, NULL, PM_NOREMOVE);
  118.    _DoneEasyWin();
  119. }
  120.  
  121.  
  122. //------------------------------------------------------------------------
  123. //
  124. // SpawnWait() - Spawn a child process, wait for termination
  125. //
  126. // Use WinExec() to fire off a child process, then synchronize with
  127. // its termination. For use with EasyWin applications.
  128. //
  129. // Inputs:
  130. //    cmdLine     Command line including executable name
  131. //    fuCmdShow   How to display new main window (see ShowWindow())
  132. //
  133. // Returns:
  134. //    -1          Big Trouble: NotifyRegister or WinExec failed
  135. //    >=0         Exit status of child
  136. //
  137. // On Error:
  138. //    Logs and displays an error message using printmsg()
  139. //
  140. //------------------------------------------------------------------------
  141.  
  142. int SpawnWait( const char *command,
  143.                const char *parameters,
  144.                const boolean synchronous,
  145.                const UINT fuCmdShow)
  146. {
  147.  
  148.    BOOL bChildIsExecuting = TRUE;
  149.    MSG msg;
  150.    int iChildExitStatus = 0;
  151.  
  152.    if ( synchronous )
  153.    {
  154.       lpfnNotifyCB = (LPFNNOTIFYCALLBACK)
  155.                            MakeProcInstance((FARPROC) NotifyCatcher,
  156.                                              _hInstance);
  157.  
  158.       if (!NotifyRegister(hOurTask, lpfnNotifyCB, NF_NORMAL))
  159.       {
  160.            FreeProcInstance(lpfnNotifyCB);
  161.            printmsg(0, "SpawnWait: NotifyRegister() failed.");
  162.            return(-1);
  163.       }
  164.    }
  165.  
  166.    //
  167.    // Start up the child proc with the given command line. To start a DOS
  168.    // box, use a .PIF file as the executable name (1st arg).
  169.    //
  170.    // WARNING! The spawned task MUST give up control to the system at
  171.    // least once before exiting! An EasyWin app that calls _DoneEasyWin()
  172.    // in an atexit() proc may never yiend to the system. In this case
  173.    // WinExec() will not return here before the spawned task terminates.
  174.    // The Notification callback will be called before WinExec() returns,
  175.    // and the hInstChild will not be set yet. Result: This task will never
  176.    // see the termination notfication of the spawned task, and SpawnWait()
  177.    // will wait forever. CAVEAT!
  178.    //
  179.    // (To insure we do yield, banner() has a call to ddelay().)
  180.  
  181.    if ( parameters == NULL )
  182.       hChildInst = WinExec( command , fuCmdShow);
  183.    else {
  184.       char buf[BUFSIZ];
  185.       strcpy( buf, command );
  186.       strcat( buf, " " );
  187.       strcat( buf, parameters );
  188.       hChildInst = WinExec( buf , fuCmdShow);
  189.    }
  190.  
  191.    if ( hChildInst < 32 )
  192.    {
  193.  
  194.       if ( synchronous )
  195.       {
  196.          NotifyUnRegister(hOurTask);
  197.          FreeProcInstance(lpfnNotifyCB);
  198.       }
  199.  
  200.       printmsg(0, "SpawnWait: WinExec(%s %s) failed. Code = %d\n",
  201.                   command,
  202.                   parameters ? parameters : "",
  203.                   (int)hChildInst);
  204.       return(-1);
  205.  
  206.    }  /* if */
  207.  
  208.    if ( ! synchronous )
  209.       return 0;
  210.  
  211.    //
  212.    // LOCAL MESSAGE LOOP - Service Windows while waiting for
  213.    // child proc to terminate.
  214.    //
  215.    while(bChildIsExecuting && GetMessage(&msg, NULL, NULL, NULL))
  216.    {
  217.       TranslateMessage(&msg);
  218.       DispatchMessage(&msg);
  219.  
  220.       if (msg.message == PM_TASKEND)
  221.       {
  222.          bChildIsExecuting = FALSE;
  223.          iChildExitStatus = (int)(LOBYTE(msg.lParam));
  224.       } /* while */